﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.ServiceLocation;

namespace IInject.Practices.ServiceLocation
{
	public class IInjectServiceLocator : ServiceLocatorImplBase
	{
		private readonly IContainer _container;

		public IInjectServiceLocator(IContainer container)
		{
			_container = container;
		}

		protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
		{
			return _container.GetAll(serviceType);
		}

		protected override object DoGetInstance(Type serviceType, string key)
		{
			return _container.Get(serviceType, key);
		}

		public bool TryGetAllInstances<T>(out IEnumerable<T> values)
		{
			try
			{
				values = GetAllInstances<T>();
				return true;
			}
			catch (ActivationException)
			{
				values = Enumerable.Empty<T>();
				return false;
			}
		}

		public bool TryGetAllInstances(Type serviceType, out IEnumerable<object> values)
		{
			try
			{
				values = GetAllInstances(serviceType);
				return true;
			}
			catch (ActivationException)
			{
				values = Enumerable.Empty<object>();
				return false;
			}
		}

		public bool TryGetInstance<T>(out T value)
		{
			return TryGetInstance<T>(null, out value);
		}

		public bool TryGetInstance<T>(string key, out T value)
		{
			object result = null;

			if (TryGetInstance(typeof(T), key, out result))
			{
				value = (T)result;
				return true;
			}

			value = default(T);
			return false;
		}

		public bool TryGetInstance(Type serviceType, string key, out object value)
		{
			try
			{
				value = GetInstance(serviceType, key);
				return true;
			}
			catch (ActivationException)
			{
				value = null;
				return false;
			}
		}
	}
}
